<template>
	<view class="treeSelect" v-show="show">
		<view class="box">
			<view class="title">
				<text>{{title}}</text>
				<view class="closeBut" @click="close">
					<image class="ico" :src="require('./images/ico_close.png')"></image>
				</view>
			</view>
			<view class="con">
				<treeSelectOne
					:props="props"
					@getChooseValue="getValue"
					@openTagChange="openTagChange"
					:checkStrictly="checkStrictly"
					:multiple="multiple"
					:data="listData"
					:allData="listData"
					:chooseMode="chooseMode"
					:showAllLevels="showAllLevels"></treeSelectOne>
			</view>
			<view class="but">
				<button @click="save" class="but yes">{{submitText}}</button>
				<button @click="close" class="but no">{{cancelText}}</button>
			</view>
		</view>
	</view>
</template>

<script>
	import treeSelectOne from "./treeSelectOne.vue";
	import {
		getTreeParents
	} from "./base.js";

	export default {
		data() {
			return {
				chooseIds: [],
				chooseItems: [],
				listData: this.value,
			}
		},
		props: {
			// 树（Tree）是否显示。
			show: Boolean,
			// 树（Tree）解构数据。
			value: Array,
			// 树（Tree），需要回显的数据，id的数组。注意multiple值需与回显值匹配。
			ids: {
				type: Array,
				default: function() {
					return [];
				}
			},
			// 是否严格的遵守父子节点不互相关联（true: 每一级都能选，false: 只能选最后一级）
			checkStrictly: {
				type: Boolean,
				default: false
			},
			// 是否多选
			multiple: {
				type: Boolean,
				default: false
			},
			// 是否返回完整路径数据集
			showAllLevels: {
				type: Boolean,
				default: true
			},
			// 选择器标题
			title: {
				type: String,
				default: '部门选择'
			},
			// 确定按钮文字
			submitText: {
				type: String,
				default: '确定'
			},
			// 取消按钮文字
			cancelText: {
				type: String,
				default: '取消'
			},
			// 选择模式，默认line，勾选模式ico
			chooseMode: {
				type: String,
				default: 'line'
			},
			// 配置选项，具体见下表
			props: {
				type: Object,
				default: function() {
					return {
						label: 'label', // 指定选项的值为选项对象的某个属性值
						id: 'id', // 指定选项的值为选项对象的某个属性值
						children: 'children', // 指定选项的子选项为选项对象的某个属性值
					};
				}
			},
		},
		components: {
			treeSelectOne,
		},
		watch: {
			// 弹窗打开后需要已选中的数据
			show: {
				handler(n) {
					this.showChooseResult();
				},
				deep: true
			},
			// 根据回显id集,回显数据
			ids: {
				handler(n) {
					this.showChooseResult();
				},
				deep: true
			},
		},
		mounted() {
			const newData = JSON.parse(JSON.stringify(this.initValue(this.listData)));
			this.listData = newData;
			this.$emit("input", this.listData);
		},
		methods: {
			// 回显展示效果
			showChooseResult() {
				this.chooseIds = this.ids;
				this.chooseItems = [];
				// 单选
				if (!this.multiple) {
					this.changeValue(this.listData, JSON.parse(JSON.stringify(this.chooseIds)));
				} else {
					const chooseIds = JSON.parse(JSON.stringify(this.chooseIds));
					chooseIds.forEach((item) => {
						this.changeValue(this.listData, item);
					});
				}
			},
			// 推完整路径，解决小程序，展开后选中父节点自动收起问题。
			openTagChange(ids, openTag) {
				this.openTagDg(this.listData, ids[ids.length - 1], openTag);
			},
			// 递归改值
			// data：树数据
			// id：展开或收起的对象id
			// openTag：状态值
			openTagDg(data, id, openTag) {
				data.forEach((item, i) => {
					if (item[this.props.id] === id) {
						item.openTag = openTag;
					}

					if (item[this.props.children] !== undefined) {
						this.openTagDg(item[this.props.children], id, openTag);
					}
				});
			},
			// 关闭
			close() {
				this.$emit("close", false);
				// this.chooseIds = [];
				// this.chooseItems = [];
			},
			// 选中的值
			save() {
				if (this.chooseIds.length > 0) {
					this.chooseItems = [];
					// 单选
					if (!this.multiple) {
						const item = this.chooseIds;
						const chooseItems = getTreeParents(this.listData, item[item.length - 1], this.props.id, []);
						if (this.showAllLevels) {
							this.chooseItems = chooseItems;
						} else {
							this.chooseItems.push(chooseItems[chooseItems.length - 1]);
						}
					} else {
						this.chooseIds.forEach((item, i) => {
							this.chooseItems.push([]);
							// console.log(item);
							const chooseItems = getTreeParents(this.listData, item[item.length - 1], this.props.id, []);
							if (this.showAllLevels) {
								this.chooseItems[i].push(chooseItems);
							} else {
								this.chooseItems[i].push(chooseItems[chooseItems.length - 1]);
							}
						});
					}
					this.$emit("getChooseValue", this.chooseIds, this.chooseItems); // 继续向上传递
					this.close();
				} else {
					uni.showToast({
						title: '您还没有选择任何项目。',
						duration: 2000,
						icon: "none"
					});
				}
			},
			// 获取tree选择的结果
			// ids的数组
			// oldChoose历史选中状态
			getValue(ids, oldChoose) {
				this.chooseItems = [];
				// 单选
				if (!this.multiple) {
					this.chooseIds = ids;
					this.changeValue(this.listData, JSON.parse(JSON.stringify(this.chooseIds)));
				} else {
					// 选中
					if (!oldChoose) {
						this.chooseIds.push(ids);
					} else {
						// 取消选中
						const nums = this.chooseIds.length;
						const tempids = ids.toString();
						let index = -1;
						for (let i = 0; i < nums; i++) {
							const temp = this.chooseIds[i].toString();
							if (temp === tempids) {
								index = i;
								break;
							}
						}
						if (index > -1) {
							this.chooseIds.splice(index, 1);
						}
					}
					this.multipleDataInit(this.listData);
					const chooseIds = JSON.parse(JSON.stringify(this.chooseIds));
					if (chooseIds.length === 0) {
						this.chooseItems = [];
					} else {
						chooseIds.forEach((item) => {
							const chooseItem = this.changeValue(this.listData, item, []);
							this.chooseItems.push(chooseItem);
						});
					}
				}
			},
			// 多选模式，一个都没选的重置
			multipleDataInit(data) {
				data.forEach((item, i) => {
					item.choose = false;
					if (item[this.props.children] !== undefined) {
						this.multipleDataInit(item[this.props.children]);
					}
				});
			},
			// 递归改值 - 只负责该值，不负责获取对象集
			// data：树数据
			// chooseIds：选择的树id数据集
			changeValue(data, chooseIds) {
				const nums = data.length;
				for (let i = 0; i < nums; i++) {
					const item = data[i];
					// 单选
					if (!this.multiple) {
						if (chooseIds[chooseIds.length - 1] === item[this.props.id]) {
							item.choose = true;
						} else {
							item.choose = false;
						}
					} else {
						if (chooseIds[chooseIds.length - 1] === item[this.props.id]) {
							item.choose = true;
						}
					}
					// 小程序选择bug优化。
					if (chooseIds[0] === item[this.props.id]) {
						chooseIds.splice(0, 1);
					}

					if (item[this.props.children] !== undefined) {
						this.changeValue(item[this.props.children], chooseIds);
					}
				}
			},
			// 初始化
			initValue(data) {
				data.forEach((item, i) => {
					item.choose = false;
					item.openTag = false;
					if (item[this.props.children] !== undefined) {
						item[this.props.children] = this.initValue(item[this.props.children]);
					}
				});
				return data;
			},
		}
	}
</script>

<style lang="scss" scoped>
	@import "./ljs-treeChoose.scss"
</style>